// объект матрицы ходов

// сама матрица
var matrix = Array(
[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255],
[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255], [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]);

var movement;   // массив движения; 0 - вправо; 1 - влево; 2 - вниз; 3 - вверх

/*  объект:
    find - свойство, кот. возвращает результат поиска кратчайшего пути;
    init - инициализация матрицы ходов и нахождение кратчайшего пути;
    find_way - возвращает массив найденного пути следования юнита к финишной точке.
 */
var Move_matrix = { N: 16,          // NxN - размер матрицы ходов (без границы)
                    Ni: 0,          // количество ходов юнита до финишной точки
                    find: false,
                    init: init_matrix,
                    find_way: function() { return movement;}
};

function init_matrix(i_top_cell, j_top_cell, i_player, j_player, i_goTo, j_goTo) {
/*  метод инициализации матрицы ходов и поиска кратчайшего пути следования юнита:
    i_top_cell, j_top_cell - координаты верхней клетки области, кот. отображается,
    это смещения (в единицах клетки) относительно [0,0] координаты матрицы карты Map_matrix;
    i_player, j_player - координаты юнита на области отображения,
    это смещение (в единицых клетки) относительно [i_top_cell, j_top_cell];
    i_goTo, j_goTo - координаты финишной точки,
    это смещение (в единицых клетки) относительно [i_top_cell, j_top_cell];
*/
    var i, j, j_cell;
    // инициализация матрицы ходов в зависимости от возможности юнита ходить по клеткам
    for(i = 1; i <= Move_matrix.N; i++, i_top_cell++) {
        j_cell = j_top_cell;
        for(j = 1; j <= Move_matrix.N; j++, j_cell++) {
            if (Map_matrix[i_top_cell][j_cell] < 5)
                matrix[i][j] = 254;
            else matrix[i][j] = 255;
        }
    }
    // отмечаем клетки, в кот. находится юнит и финишную клетку
    matrix[i_player + 1][j_player + 1] = 253;
    matrix[i_goTo + 1][j_goTo + 1] = 0;
    Find_Way();    // вызов метода нахождения пути следования юнита
    if (Move_matrix.find)   // если путь следования найден - формирование массива ходов юнита
        Create_Movement(i_player, j_player);
}

function Find_Way() {
    // метод нахождения пути следования юнита
    var Nk = Move_matrix.N * Move_matrix.N, ind = 0;
    Move_matrix.Ni = 0;
    // Ni - количество ходов юнита до финишной точки, Nk - max возможное кол-во ходов юнита
    while(Move_matrix.Ni < Nk) {
        for (i = 1; i <= Move_matrix.N; i++) {
            for (j = 1; j <= Move_matrix.N; j++) {
                if (matrix[i][j] == Move_matrix.Ni) {
                    if (matrix[i+1][j] == 253) { ind = 1; break;}
                    if (matrix[i+1][j] == 254) { matrix[i+1][j] = Move_matrix.Ni + 1;}
                    if (matrix[i-1][j] == 253) { ind = 1; break;}
                    if (matrix[i-1][j] == 254) { matrix[i-1][j] = Move_matrix.Ni + 1;}
                    if (matrix[i][j+1] == 253) { ind = 1; break;}
                    if (matrix[i][j+1] == 254) { matrix[i][j+1] = Move_matrix.Ni + 1;}
                    if (matrix[i][j-1] == 253) { ind = 1; break;}
                    if (matrix[i][j-1] == 254) { matrix[i][j-1] = Move_matrix.Ni + 1;}
                }
            }
        }
        Move_matrix.Ni++;
        if (ind) break;
    }
    if (Move_matrix.Ni == Nk) Move_matrix.find = false; // путь не найден
    else if (Move_matrix.Ni != Nk) Move_matrix.find = true; // путь найден
}

function Create_Movement(i_pl, j_pl) {
    // метод формирования массива движения юнита
    movement = new Array(Move_matrix.Ni);
    var x1 = i_pl + 1, y1 = j_pl + 1, min = 254, x2, y2;
    for (i = 0; i < Move_matrix.Ni; i++) {
        if (matrix[x1][y1] == 0) { break;}
        if (matrix[x1+1][y1] < min) { min = matrix[x1+1][y1]; x2 = x1+1; y2 = y1; movement[i] = 0;}
        if (matrix[x1-1][y1] < min) { min = matrix[x1-1][y1]; x2 = x1-1; y2 = y1; movement[i] = 1;}
        if (matrix[x1][y1+1] < min) { min = matrix[x1][y1+1]; x2 = x1; y2 = y1+1; movement[i] = 2;}
        if (matrix[x1][y1-1] < min) { min = matrix[x1][y1-1]; x2 = x1; y2 = y1-1; movement[i] = 3;}
        x1 = x2;
        y1 = y2;
    }
}